local startup = {}
mod = {
    startup = startup, --注入自启的mod列表
}
---@class cMod
local cMod = {
    modName = '',
    

}
cMod.__index = cMod

local _loded = {}
---加载一个MOD,首次载入会执行该Mod的Main方法
---@param modName string 路径如template
---@return cMod
function mod:load( modName )
    if _loded[modName] then return _loded[modName] end

    local strPath = modName:gsub("\\", "." )
    local suc,tblInfo = xpcall(require,
        function(msg)
            return debug.traceback('读取MOO信息出错:\n' .. msg)
        end,
        'Mods.'.. strPath .. ".modinfo"
    )

    assert( type(tblInfo)=='table', ("ModInfo[%s]未按规定返回table"):format(modName) )

    local env = setmetatable({},{
        __index = function (t,k)
            return tblInfo[k] or _G[k]
        end
    })

    local func = loadfile(Root .. '\\Mods\\' .. modName .. '\\modmain.lua', 'bt', env)
    assert(func,  ("ModMain[%s]加载失败！"):format(modName) )
    ---@type cMod
    local _mod = func()
    assert(type(_mod) == 'table',  ("ModMain[%s]格式错误,目标应该返回一个具有Main方法的表!"):format(modName) )

    ---对Mod环境挂接
    local mt = getmetatable(_mod)
    if mt then
        local _index = mt.__index
        if type(_index) == 'function' then
            mt.__index = function (t,k)
                return cMod[k] or _index(t,k)
            end
        elseif type(_index) == 'table' then
            mt.__index = function (t,k)
                return cMod[k] or _index[k]
            end
        else
            mt.__index = function (t,k)
                return cMod[k] or _index
            end
        end
    else
        setmetatable( _mod, cMod )
    end
    _mod.modName = modName
    _loded[modName] = _mod or {}

    --载入Mod
    _mod:Main()

    return _mod
end

local table_insert = table_insert
---生成注入的Mod自启lua
function mod:genCode()
    local code = {}
    for index, modName in ipairs(startup) do
        table_insert( code, ('require "Mods.%s"\n'):format( modName:gsub("\\", "." ) ) )
    end
    local folder = ('%s\\debug\\%s\\temp\\map\\Mods'):format( Root, builder.map )
    
    mkdir( folder )
    local output = ('%s\\%s'):format( folder,  'startup.lua' )
    
    local file = io.open( output, 'w+' )
    assert(file, 'Mod启动代码注入失败,一些Mod功能将会失效')
    file:write( table.concat(code) )
    file:close()

end

---导入文件
---@param filename string 在当前mod\res目录内的文件名(不包含res\)
---@param output string 地图内的路径包含文件名
function cMod:importFile( filename, output )
    local input = ('%s\\Mods\\%s\\res\\%s'):format( Root, self.modName, filename )
    output = ('%s\\debug\\%s\\temp\\map\\%s'):format( Root, builder.map, output )
    
    local folder = output:sub(1,output:find_r("\\"))

    
    mkdir( folder )

    copy( input, output )
end

---导入文件
---@param output string 地图内的路径包含文件名
---@---@param str string 文件内容
function cMod:importFileByStr(  output, str  )
    output = ('%s\\debug\\%s\\temp\\map\\%s'):format( Root, builder.map, output )
    local folder = output:sub(1,output:find_r("\\"))

    mkdir( folder )
    
    write(output, str)
end

---导入文件夹
---@param input string 在当前mod\res目录内的文件夹(不包含res\)
---@param output string 地图内的路径包含文件名
function cMod:importFolder( input, output )
    input = ('%s\\Mods\\%s\\res\\%s'):format( Root, self.modName, input )
    output = ('%s\\debug\\%s\\temp\\map\\%s'):format( Root, builder.map, output )

    local folder = output:sub(1,output:find_r("\\"))

    mkdir( folder )
    
    xcopy( input, output )
end

---开启进入游戏时的Mod自启
---需要导入一个lua在Mod目录下,导入后名称为Init.lua
---@param filename string res下的一个lua文件
function cMod:startup( filename )
    if startup[self.modName] then
        return
    end
    startup[self.modName] = true
    table_insert( startup, self.modName )
    self:importFile( filename, ('Mods\\%s\\Init.lua'):format(self.modName) )
end

---获取Mod的完整目录
---@return string 末尾不包含\
function cMod:getModPath( )
    return ('%s\\Mods\\%s'):format( Root, self.modName )
end

